#include <tchar.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>

#include "GoogleService.hpp"
#include "GoogleReader.hpp"
#include "XmlUtils.hpp"
#include "GoogleData.hpp"

static bool WriteTextFile(const char* pName, int nSeq, const char* pText)
{
#ifndef UNDER_CE
	char txt[200];
	sprintf(txt, "%s-%d.xml", pName, nSeq);
	return XmlUtils::WriteTextToFile(txt, pText);
#else
	return true;
#endif
}
/*
static bool StringToTimeT(const char* pStr, unsigned int& nTimeT)
{
	char vv[22];
	strcpy(vv, pStr);
	vv[4] = '\0';
	vv[7] = '\0';
	vv[10] = '\0';
	vv[13] = '\0';
	vv[16] = '\0';
	vv[19] = '\0';
	struct tm t;
	//nTimeT = 0;
	//t = *localtime((const time_t*)&nTimeT);
	t.tm_year = atoi(vv+0) - 1900;
	t.tm_mon = atoi(vv+5);
	t.tm_mday = atoi(vv+8);
	t.tm_hour = atoi(vv+11);
	t.tm_min = atoi(vv+14);
	t.tm_sec = atoi(vv+15);
	nTimeT = (unsigned int)mktime32(&t);
	//struct tm* p;
	//p = localtime((const time_t*)&nTimeT);
	return true;
}
*/
Subscription::Subscription(const char* pUrl, const char* pTitle, const char* pLast)
{
	sid = -1;
	object = pUrl;
	title = pTitle;
	last = pLast;
}

Item::Item(const char* pId, const char* pUrl, const char* pTitle, const char* pUpdated, const char* pSummary, bool bRead)
{
	cid = -1;
	sid = -1;
	id = pId;
	url = pUrl;
	title = pTitle;
	updated = pUpdated;
	summary = pSummary;
	read = bRead;
}

CGoogleReader::CGoogleReader(LPCTSTR pSource) : CGoogleService(pSource, true, _T("reader"))
{
}

#define TEMP_BUFSIZE		200*1024
#include <stdio.h>

bool CGoogleReader::GetList(std::vector<Subscription>& List)
{
	static int seq = 0;
	seq++;

	TiXmlDocument doc;
	TiXmlElement* pObject;
	List.clear();

	char* pData;
	DWORD dwDataSize;

	pData = (char*)malloc(TEMP_BUFSIZE);
	if(!pData) return false;
	dwDataSize = TEMP_BUFSIZE;
	if(!HttpGet(_T("/reader/api/0/subscription/list"), pData, dwDataSize, true)) {
		free(pData);
		return false;
	}
	WriteTextFile("List", seq, pData);
	doc.Clear();
	doc.Parse(pData);
	free(pData);
	if(doc.Error()) return false;
	pObject = XmlUtils::GetElement(XmlUtils::GetElement(doc.RootElement(), "list"), "object");
	while(pObject) {
		const char* pId = GoogleData::GetData(pObject, "string", "id");
		const char* pTitle = GoogleData::GetData(pObject, "string", "title");
		if(pId && pTitle) {
			List.push_back(Subscription(pId, pTitle));
		}
		pObject = pObject->NextSiblingElement("object");
	}
/*
	pData = (char*)malloc(TEMP_BUFSIZE);
	if(!pData) return false;
	dwDataSize = TEMP_BUFSIZE;
	if(!HttpGet(_T("/reader/api/0/unread-count?all=true"), pData, dwDataSize, true)) {
		free(pData);
		return false;
	}
	WriteTextFile("Unread", seq, pData);
	doc.Clear();
	doc.Parse(pData);
	free(pData);
	if(doc.Error()) return false;
	pObject = XmlUtils::GetElement(XmlUtils::GetElement(doc.RootElement(), "list"), "object");
	while(pObject) {
		const char* pId = GoogleData::GetData(pObject, "string", "id");
		const char* pCount = GoogleData::GetData(pObject, "number", "count");
		if(pId && pCount) {
			for(size_t i=0; i<List.size(); i++) {
				if(List[i].id==pId) List[i].unread = atoi(pCount);
			}
		}
		pObject = pObject->NextSiblingElement("object");
	}
*/
	return true;
}

bool CGoogleReader::GetFeed(LPCTSTR pId, std::vector<Item>& Items, LPCTSTR pLast)
{
	static int seq = 0;
	seq++;

	TiXmlDocument doc;
	TiXmlElement* pEntry;
	Items.clear();

	TCHAR txt[200];
	TCHAR url[200];
	if(!UrlEncode(pId, url, sizeof(url))) return false;
	if(pLast) {
		_sntprintf(txt, sizeof(txt), _T("/reader/atom/%s?n=10&ot=%s"), url, pLast);
	} else {
		_sntprintf(txt, sizeof(txt), _T("/reader/atom/%s?n=10"), url);
	}

	char* pData;
	DWORD dwDataSize;

	pData = (char*)malloc(TEMP_BUFSIZE);
	if(!pData) return false;
	dwDataSize = TEMP_BUFSIZE;
	if(!HttpGet(txt, pData, dwDataSize, true)) {
		free(pData);
		return false;
	}
	WriteTextFile("Feed", seq, pData);
	doc.Clear();
	doc.Parse(pData);
	free(pData);
	if(doc.Error()) return false;
	pEntry = XmlUtils::GetElement(doc.RootElement(), "entry");
	while(pEntry) {
		const char* pId = XmlUtils::GetText(pEntry, "id");
		const char* pUrl = XmlUtils::GetAttribute(XmlUtils::GetElement(pEntry, "link"), "href");
		const char* pTitle = XmlUtils::GetText(pEntry, "title");
		const char* pUpdated = XmlUtils::GetAttribute(pEntry, "gr:crawl-timestamp-msec");

		const char* pSummary = XmlUtils::GetText(pEntry, "summary");
		if(!pSummary) pSummary = XmlUtils::GetText(pEntry, "content");
		if(!pSummary) pSummary = "";
		bool bRead = false;
		if(!pId || !pUrl || !pTitle || !pUpdated || !pSummary) return false;

		char vv[30];
		strcpy(vv, pUpdated);
		if(strlen(vv)>3) vv[strlen(vv)-3] = '\0';
		pUpdated = vv;
		assert(strcmp(XmlUtils::GetAttribute(XmlUtils::GetElement(pEntry, "link"), "rel"), "alternate")==0);
		for(TiXmlElement* pCategory=XmlUtils::GetElement(pEntry, "category"); pCategory; pCategory=pCategory->NextSiblingElement("category")) {
			const char* pTerm = XmlUtils::GetAttribute(pEntry, "term");
			if(pTerm) {
				if(strstr(pTerm, "/state/com.google/read")) {
					bRead = true;
					break;
				}
			}
		}
		Items.push_back(Item(pId, pUrl, pTitle, vv, pSummary, bRead));
		pEntry = pEntry->NextSiblingElement("entry");
	}
	return true;
}
